home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcl / src-16f.lha / compiler / rt / move.lisp < prev    next >
Encoding:
Text File  |  1991-11-09  |  10.3 KB  |  357 lines

  1. ;;; -*- Package: RT; Log: c.log -*-
  2. ;;;
  3. ;;; **********************************************************************
  4. ;;; This code was written as part of the Spice Lisp project at
  5. ;;; Carnegie-Mellon University, and has been placed in the public domain.
  6. ;;; If you want to use this code or any part of Spice Lisp, please contact
  7. ;;; Scott Fahlman (FAHLMAN@CMUC). 
  8. ;;; **********************************************************************
  9. ;;;
  10. ;;; $Header: move.lisp,v 1.5 91/11/09 02:37:19 wlott Exp $
  11. ;;;
  12. ;;; This file contains the IBM RT VM definition of operand loading/saving and the
  13. ;;; Move VOP.
  14. ;;;
  15. ;;; Written by Rob MacLachlan.
  16. ;;; MIPS conversion by William Lott.
  17. ;;; IBM RT conversion by William Lott and Bill Chiles.
  18. ;;;
  19.  
  20. (in-package "RT")
  21.  
  22.  
  23. (define-move-function (load-immediate 1) (vop x y)
  24.   ((null immediate)
  25.    (any-reg word-pointer-reg descriptor-reg))
  26.   (let ((val (tn-value x)))
  27.     (etypecase val
  28.       (integer
  29.        (inst li y (fixnum val)))
  30.       (null
  31.        (move y null-tn))
  32.       (symbol
  33.        (load-symbol y val))
  34.       (character
  35.        (inst li y (logior (ash (char-code val) type-bits)
  36.               base-char-type))))))
  37.  
  38. (define-move-function (load-number 1) (vop x y)
  39.   ((immediate)
  40.    (signed-reg unsigned-reg))
  41.   (inst li y (tn-value x)))
  42.  
  43. (define-move-function (load-base-char 1) (vop x y)
  44.   ((immediate) (base-char-reg))
  45.   (inst li y (char-code (tn-value x))))
  46.  
  47. (define-move-function (load-system-area-pointer 1) (vop x y)
  48.   ((immediate) (sap-reg))
  49.   (inst li y (sap-int (tn-value x))))
  50.  
  51. (define-move-function (load-constant 5) (vop x y)
  52.   ((constant) (descriptor-reg))
  53.   (loadw y code-tn (tn-offset x) other-pointer-type))
  54.  
  55. (define-move-function (load-stack 5) (vop x y)
  56.   ((control-stack) (any-reg word-pointer-reg descriptor-reg))
  57.   (load-stack-tn y x))
  58.  
  59. (define-move-function (load-number-stack 5) (vop x y)
  60.   ((base-char-stack) (base-char-reg)
  61.    (sap-stack) (sap-reg)
  62.    (signed-stack) (signed-reg)
  63.    (unsigned-stack) (unsigned-reg))
  64.   (load-stack-tn y x vop))
  65.  
  66. (define-move-function (store-stack 5) (vop x y)
  67.   ((any-reg word-pointer-reg descriptor-reg) (control-stack))
  68.   (store-stack-tn x y))
  69.  
  70. (define-move-function (store-number-stack 5) (vop x y)
  71.   ((base-char-reg) (base-char-stack)
  72.    (sap-reg) (sap-stack)
  73.    (signed-reg) (signed-stack)
  74.    (unsigned-reg) (unsigned-stack))
  75.   (store-stack-tn x y vop))
  76.  
  77. (define-move-function (word-pointer-copy 1) (vop x y)
  78.   ((word-pointer-reg) (any-reg)
  79.    (any-reg) (word-pointer-reg))
  80.   (move y x))
  81.  
  82.  
  83.  
  84. ;;;; The Move VOP:
  85.  
  86. (define-vop (move)
  87.   (:args (x :target y
  88.         :scs (any-reg word-pointer-reg descriptor-reg)
  89.         :load-if (not (location= x y))))
  90.   (:results (y :scs (any-reg word-pointer-reg descriptor-reg)
  91.            :load-if (not (location= x y))))
  92.   (:effects)
  93.   (:affected)
  94.   (:generator 0
  95.     (move y x)))
  96.  
  97. (define-move-vop move :move
  98.   (any-reg word-pointer-reg descriptor-reg)
  99.   (any-reg word-pointer-reg descriptor-reg))
  100.  
  101. ;;; Make Move the check VOP for T so that type check generation doesn't think
  102. ;;; it is a hairy type.  This also allows checking of a few of the values in a
  103. ;;; continuation to fall out.
  104. ;;;
  105. (primitive-type-vop move (:check) t)
  106.  
  107. ;;; MOVE-ARGUMENT -- VOP.
  108. ;;;
  109. ;;; This is used for moving descriptor values into another frame for argument
  110. ;;; or known value passing.
  111. ;;;
  112. (define-vop (move-argument)
  113.   (:args (x :target y
  114.         :scs (any-reg word-pointer-reg descriptor-reg))
  115.      (fp :scs (word-pointer-reg)
  116.          :load-if (not (sc-is y any-reg descriptor-reg))))
  117.   (:results (y))
  118.   (:generator 0
  119.     (sc-case y
  120.       ((any-reg word-pointer-reg descriptor-reg)
  121.        (move y x))
  122.       (control-stack
  123.        (storew x fp (tn-offset y))))))
  124. ;;;
  125. (define-move-vop move-argument :move-argument
  126.   (any-reg word-pointer-reg descriptor-reg)
  127.   (any-reg word-pointer-reg descriptor-reg))
  128.  
  129.  
  130.  
  131. ;;;; ILLEGAL-MOVE
  132.  
  133. ;;; ILLEGAL-MOVE -- VOP.
  134. ;;;
  135. ;;; This VOP exists just to begin the lifetime of a TN that couldn't be written
  136. ;;; legally due to a type error.  An error is signalled before this VOP is so
  137. ;;; we don't need to do anything (not that there would be anything sensible to
  138. ;;; do anyway.)
  139. ;;;
  140. (define-vop (illegal-move)
  141.   (:args (x) (type))
  142.   (:results (y))
  143.   (:ignore y)
  144.   (:vop-var vop)
  145.   (:save-p :compute-only)
  146.   (:generator 666
  147.     (error-call vop object-not-type-error x type)))
  148.  
  149.  
  150.  
  151. ;;;; Moves and coercions:
  152.  
  153. ;;; These MOVE-TO-WORD VOPs move a tagged integer to a raw full-word
  154. ;;; representation.  Similarly, the MOVE-FROM-WORD VOPs converts a raw integer
  155. ;;; to a tagged bignum or fixnum.
  156.  
  157. ;;; MOVE-TO-WORD/FIXNUM -- VOP.
  158. ;;;
  159. ;;; Arg is a fixnum, so just put it in a non-descriptor register and shift it.
  160. ;;;
  161. (define-vop (move-to-word/fixnum)
  162.   (:args (x :scs (any-reg descriptor-reg) :target y))
  163.   (:results (y :scs (signed-reg unsigned-reg)))
  164.   (:arg-types tagged-num)
  165.   (:note "fixnum untagging")
  166.   (:generator 2
  167.     (move y x)
  168.     (inst sar y 2)))
  169. ;;;
  170. (define-move-vop move-to-word/fixnum :move
  171.   (any-reg descriptor-reg) (signed-reg unsigned-reg))
  172.  
  173. ;;; MOVE-TO-WORD-C -- VOP.
  174. ;;; 
  175. ;;; Arg is a non-immediate constant, load it.
  176. ;;;
  177. (define-vop (move-to-word-c)
  178.   (:args (x :scs (constant)))
  179.   (:results (y :scs (signed-reg unsigned-reg)))
  180.   (:note "constant load")
  181.   (:generator 1
  182.     (inst li y (tn-value x))))
  183. ;;;
  184. (define-move-vop move-to-word-c :move
  185.   (constant) (signed-reg unsigned-reg))
  186.  
  187. ;;; MOVE-TO-WORD/INTEGER -- VOP.
  188. ;;;
  189. ;;; Arg is a fixnum or bignum, figure out which and load if necessary.
  190. ;;;
  191. (define-vop (move-to-word/integer)
  192.   (:args (x :scs (descriptor-reg) :to :save))
  193.   (:results (y :scs (signed-reg unsigned-reg)))
  194.   (:note "integer to untagged word coercion")
  195.   (:temporary (:scs (non-descriptor-reg)) temp)
  196.   (:generator 8
  197.     (let ((done (gen-label)))
  198.       (inst nilz temp x 3)
  199.       (move y x)
  200.       (inst bcx :eq done)
  201.       (inst sar y 2)
  202.       ;; If it's a bignum, throw away what we computed in y.
  203.       (loadw y x bignum-digits-offset other-pointer-type)
  204.       (emit-label done))))
  205. ;;;
  206. (define-move-vop move-to-word/integer :move
  207.   (descriptor-reg) (signed-reg unsigned-reg))
  208.  
  209.  
  210. ;;; MOVE-FROM-WORD/FIXNUM -- VOP.
  211. ;;;
  212. ;;; Since the result is know to be a fixnum, we can shift in the tag bits
  213. ;;; without fear of needing a bignum.
  214. ;;;
  215. (define-vop (move-from-word/fixnum)
  216.   (:args (x :scs (signed-reg unsigned-reg) :target temp))
  217.   (:temporary (:scs (non-descriptor-reg)
  218.             :from (:argument 0) :to (:result 0) :target y)
  219.           temp)
  220.   (:results (y :scs (any-reg descriptor-reg)))
  221.   (:result-types tagged-num)
  222.   (:note "fixnum tagging")
  223.   (:generator 3
  224.     (move temp x)
  225.     (inst sl temp 2)
  226.     (move y temp)))
  227. ;;;
  228. (define-move-vop move-from-word/fixnum :move
  229.   (signed-reg unsigned-reg) (any-reg descriptor-reg))
  230.  
  231. ;;; MOVE-FROM-SIGNED -- VOP.
  232. ;;;
  233. ;;; Result may be a bignum, so we have to check whether shifting to make room
  234. ;;; for tag bits results in a fixnum.  Use a worst-case cost to make sure
  235. ;;; people know they may be number consing.
  236. ;;;
  237. (define-vop (move-from-signed)
  238.   (:args (arg :scs (signed-reg unsigned-reg) :target x))
  239.   (:results (y :scs (any-reg descriptor-reg)))
  240.   (:temporary (:scs (non-descriptor-reg) :from (:argument 0)) x temp)
  241.   (:temporary (:scs (word-pointer-reg)) alloc)
  242.   (:note "signed word to integer coercion")
  243.   (:generator 25
  244.     (move x arg)
  245.     (let ((fixnum (gen-label))
  246.       (done (gen-label)))
  247.       (move temp x)
  248.       (inst sar temp 29)
  249.       (inst bcx :eq fixnum)
  250.       (inst not temp)
  251.       (inst bc :eq fixnum)
  252.       
  253.       (with-fixed-allocation (y temp alloc bignum-type 2)
  254.     (storew x y bignum-digits-offset other-pointer-type))
  255.       (inst b done)
  256.       
  257.       (emit-label fixnum)
  258.       (move y x)
  259.       (inst sl y 2)
  260.       (emit-label done))))
  261. ;;;
  262. (define-move-vop move-from-signed :move
  263.   (signed-reg) (descriptor-reg))
  264.  
  265.  
  266. ;;; MOVE-FROM-UNSIGNED -- VOP.
  267. ;;;
  268. ;;; Check for fixnum, and possibly allocate one or two word bignum result.  Use
  269. ;;; a worst-case cost to make sure people know they may be number consing.
  270. ;;;
  271. (define-vop (move-from-unsigned)
  272.   (:args (arg :scs (signed-reg unsigned-reg) :target x))
  273.   (:results (y :scs (any-reg descriptor-reg)))
  274.   (:temporary (:scs (non-descriptor-reg) :from (:argument 0)) x temp)
  275.   (:temporary (:scs (word-pointer-reg)) alloc)
  276.   (:note "unsigned word to integer coercion")
  277.   (:generator 21
  278.     (move x arg)
  279.     (let ((done (gen-label))
  280.       (bignum (gen-label))
  281.       (one-word (gen-label)))
  282.       (move temp x)
  283.       (inst sar temp 29)
  284.       (inst bnc :eq bignum)
  285.       (inst sl x 2)
  286.       (move y x)
  287.       (emit-label done)
  288.  
  289.       (assemble (*elsewhere*)
  290.     (emit-label bignum)
  291.     (pseudo-atomic (temp)
  292.       (load-symbol-value alloc *allocation-pointer*)
  293.       (inst cal y alloc other-pointer-type)
  294.       (inst cal alloc alloc (pad-data-block (1+ bignum-digits-offset)))
  295.       (inst c x 0)
  296.       (inst bncx :lt one-word)
  297.       (inst li temp (logior (ash 1 type-bits) bignum-type))
  298.       (inst cal alloc alloc
  299.         (- (pad-data-block (+ 2 bignum-digits-offset))
  300.            (pad-data-block (1+ bignum-digits-offset))))
  301.       (inst li temp (logior (ash 2 type-bits) bignum-type))
  302.       (emit-label one-word)
  303.       (store-symbol-value alloc *allocation-pointer*)
  304.       (storew temp y 0 other-pointer-type)
  305.       (storew x y bignum-digits-offset other-pointer-type))
  306.     (load-symbol-value temp *internal-gc-trigger*)
  307.     (inst tlt temp alloc)
  308.     (inst b done)))))
  309. ;;;
  310. (define-move-vop move-from-unsigned :move
  311.   (unsigned-reg) (descriptor-reg))
  312.  
  313.  
  314. ;;; Move untagged numbers.
  315. ;;;
  316. (define-vop (word-move)
  317.   (:args (x :target y
  318.         :scs (signed-reg unsigned-reg)
  319.         :load-if (not (location= x y))))
  320.   (:results (y :scs (signed-reg unsigned-reg)
  321.            :load-if (not (location= x y))))
  322.   (:effects)
  323.   (:affected)
  324.   (:note "word integer move")
  325.   (:generator 0
  326.     (move y x)))
  327. ;;;
  328. (define-move-vop word-move :move
  329.   (signed-reg unsigned-reg) (signed-reg unsigned-reg))
  330.  
  331.  
  332. ;;; Move untagged number arguments/return-values.
  333. ;;;
  334. (define-vop (move-word-argument)
  335.   (:args (x :target y
  336.         :scs (signed-reg unsigned-reg))
  337.      (fp :scs (word-pointer-reg)
  338.          :load-if (not (sc-is y sap-reg))))
  339.   (:results (y))
  340.   (:note "word integer argument move")
  341.   (:generator 0
  342.     (sc-case y
  343.       ((signed-reg unsigned-reg)
  344.        (move y x))
  345.       ((signed-stack unsigned-stack)
  346.        (storew x fp (tn-offset y))))))
  347. ;;;
  348. (define-move-vop move-word-argument :move-argument
  349.   (descriptor-reg any-reg signed-reg unsigned-reg) (signed-reg unsigned-reg))
  350.  
  351.  
  352. ;;; Use standard MOVE-ARGUMENT + coercion to move an untagged number to a
  353. ;;; descriptor passing location.
  354. ;;;
  355. (define-move-vop move-argument :move-argument
  356.   (signed-reg unsigned-reg) (any-reg descriptor-reg))
  357.